import React from 'react';
import { Button, Col, DatePicker, Drawer, Input, InputNumber, List, Modal, Row } from 'antd';
import { Form, Icon } from '@ant-design/compatible';
import { connect } from 'dva';
import { PageHeaderLayout, StandardTable, IconButton, PageCard } from '../../components';
import tools from '../../utils';
import { pageSize, modalWidth } from '../../../config';
import Authorized from '../../utils/Authorized';
import moment from 'moment';
import Editor from 'react-umeditor';
import htmlFormat from '../../utils/htmlFormat';

const reqApi = 'notice';
const formItemLayout = {
  labelCol: { md: 3 },
  wrapperCol: { md: 21 },
};
const formItemLayout3 = {
  labelCol: { md: 7, xs: 7 },
  wrapperCol: { md: 17, xs: 17 },
};
const editorIcons = [
  "bold italic underline strikethrough | forecolor backcolor |",
  "fontsize fontfamily | justifyleft justifycenter justifyright |",
  "spechars inserttable | indent outdent |",
  "insertorderedlist insertunorderedlist | superscript subscript |",
  "fullscreen | tolowercase",
];

class page extends React.Component {
  state = {
    loading: false,
    visible: false,
    dialogLoading: false,
    dialogTitle: "",
    dialogAction: "",
    selectedRows: [],
    editId: "", // 编辑时记下此id, 等到保存时把此id带过去
    editorText: "", // 富文本编辑的文字内容
    visibleSend: false,
  };

  componentDidMount() {
    this.funcGetListData();
  }

  // 获取列表数据
  funcGetListData = () => {
    this.setState({
      loading: true,
      selectedRows: [], // 换页时清除表格行选中状态
    });

    const { dispatch } = this.props;

    dispatch({
      type: reqApi + '/list',
      payload: {
        currentPage: 1,
        pageSize: 1000,
      },
    }).then(() => this.setState({ loading: false }));
  };

  // 表格列
  columns = () => {
    const { props } = this;

    return [
      {
        title: '公告标题',
        dataIndex: 'title',
        render: (text, record) => (
          <div>
            {moment().isBetween(record.beginTime, record.endTime) ? (
              <a onClick={() => this.funcSend(record.id)}>
                <Icon
                  type='message'
                  theme='twoTone'
                  title='发送订阅消息'
                  style={{ marginRight: 8 }}
                />
              </a>
            ) : null}

            <Authorized authority={() => tools.funcCheckValid(props, 'edit')} noMatch={text}>
              <a
                title="编辑"
                onClick={() => {
                  this.funcOpenForm(record);
                  this.setState({ editId: record.id });
                }}
              >
                {text}
              </a>
            </Authorized>
          </div>
        ),
      },
      {
        title: "开始时间",
        dataIndex: "beginTime",
        width: 150,
        render: text => <span style={{ color: "gray" }}>{text.substr(0, 16)}</span>,
      },
      {
        title: "结束时间",
        dataIndex: "endTime",
        width: 150,
        render: text => <span style={{ color: "gray" }}>{text.substr(0, 16)}</span>,
      },
    ];
  };

  // 内容列表
  contentTable = () => {
    const { state, props } = this;
    const { data } = props[reqApi];

    return (
      <div>
        <Button.Group>
          <Authorized authority={() => tools.funcCheckValid(props, 'create')}>
            <IconButton
              text='新增公告'
              onClick={() => this.funcOpenForm()}
              style={{ marginBottom: 16 }}
            />
          </Authorized>
          <Authorized authority={() => tools.funcCheckValid(props, 'delete')}>
            <IconButton
              text='删除公告'
              type='danger'
              onClick={this.funcDelete}
              disabled={!state.selectedRows.length}
              style={{ marginBottom: 16 }}
            />
          </Authorized>
        </Button.Group>
        <StandardTable
          loading={state.loading}
          columns={this.columns()}
          data={{
            list: data,
            pagination: false,
          }}
          selectedRows={state.selectedRows}
          onSelectRow={(selectedRows) => this.setState({ selectedRows })}
          scrollX={window.isMobile ? 800 : false}
        />
      </div>
    );
  };

  // 弹出表单
  funcOpenForm = (record) => {
    const dialogAction = record ? 'edit' : 'create';

    this.setState({
      visible: true,
      dialogTitle: tools.funcDlgTitle('公告', dialogAction),
      dialogAction,
      editorText: '',
    }, () => {
      const { form, dispatch } = this.props;

      form.resetFields();

      if (dialogAction === 'edit') {
        const { title, sequ, beginTime, endTime, id } = record;
        const newRecord = {
          title,
          sequ,
          beginTime: moment(beginTime, 'YYYY-MM-DD HH:mm'),
          endTime: moment(endTime, 'YYYY-MM-DD HH:mm'),
        };
        form.setFieldsValue(newRecord);

        // 调用回显接口获取"content"的值
        dispatch({
          type: reqApi + '/echo',
          payload: {
            action: 'edit',
            id,
          },
        }).then(() => {
          const { props } = this;
          this.setState({
            editorText: props[reqApi].echoModel.content,
          }, this.funcReadyEditor);
        });
      } else setTimeout(this.funcReadyEditor, 0);
    });
  };

  // 删除
  funcDelete = () => {
    const { state } = this;
    let names = [], ids = [];
    for (let i = 0; i < state.selectedRows.length; i += 1) {
      const item = state.selectedRows[i];
      const { id, title, content } = item;
      names.push(title || content);
      ids.push(id);
    }

    Modal.confirm({
      title: "删除？",
      content: (
        <div>
          <div>你即将删除以下记录：</div>
          <div>{names + ""}</div>
          <div>请确认是否删除？</div>
        </div>
      ),
      okText: "是",
      okType: "danger",
      cancelText: "否",
      onOk: () => {
        this.setState({ loading: true });

        const { dispatch } = this.props;
        dispatch({
          type: reqApi + '/dele',
          payload: { ids: ids + "" },
        }).then(() => {
          const { props } = this;
          const { success } = props[reqApi];
          if (success) this.funcGetListData();
          else this.setState({ loading: false });
        });
      },
    });
  };

  // 保存
  funcSave = () => {
    const { dialogAction, editId, editorText } = this.state;
    const { form, dispatch } = this.props;

    form.validateFields((error, values) => {
      if (error) return error;

      const model = {
        ...values,
        content: editorText,
      };
      if (dialogAction === "edit") model.id = editId;
      if (!values.userId || values.userId === '0')
        model.userId = tools.funcGetUserId();
      if (values.beginTime)
        model.beginTime = values.beginTime.format('YYYY-MM-DD HH:mm:ss');
      if (values.endTime)
        model.endTime = values.endTime.format('YYYY-MM-DD HH:mm:ss');

      this.setState({ dialogLoading: true });

      dispatch({
        type: reqApi + '/' + dialogAction,
        payload: { model },
      }).then(() => {
        this.setState({ dialogLoading: false });

        const { props } = this;
        const { success } = props[reqApi];
        if (success) {
          this.setState({ visible: false });
          this.funcGetListData();
        }
      });
    });
  };

  // 发送订阅消息
  funcSend = (noticeId) => {
    this.setState({ loading: true });

    const { dispatch } = this.props;
    dispatch({
      type: reqApi + '/send',
      payload: { noticeId },
    }).then(() => {
      this.setState({ loading: false });

      const { props } = this;
      const { success, taskTotal, dataFail, errMsg } = props[reqApi];
      if (!success && taskTotal && dataFail.length && errMsg) {
        this.setState({ visibleSend: true });
      }
    });
  };

  // 准备编辑器
  funcReadyEditor = () => {
    // 编辑器的高度自适应
    let dom = document.getElementsByClassName("editable-range")[0];
    if (dom) {
      dom.style.overflow = "auto";
      dom.style.height = "calc(100vh - 317px)";
      dom.setAttribute('dataHeight', 'calc(100vh - 317px)');
    }

    // 修复编辑器工具栏高度
    dom = document.getElementsByClassName("editor-toolbar")[0];
    if (dom) {
      dom.style.lineHeight = "normal";
    }

    // 不用编辑器原有的代码切换, 改为自己实现
    dom = document.getElementsByClassName("icon-tolowercase")[0];
    if (dom) {
      dom.title = "源代码";
      dom.className = "editor-icon icon-source";
      dom.onclick = this.funcToggleSource;
    }

    let txt = document.getElementById("txt_source");
    if (!txt) {
      dom = document.getElementsByClassName("editor-contenteditable-div")[0];
      if (dom) {
        txt = document.createElement("textarea");
        txt.id = "txt_source";
        txt.style.width = "100%";
        txt.style.border = "none";
        txt.style.outline = "none";
        txt.style.backgroundColor = '#002766';
        txt.style.color = '#40a9ff';
        txt.style.lineHeight = "normal";
        txt.style.fontSize = "small";
        txt.style.fontFamily = "monospace";
        txt.style.wordWrap = "normal";
        txt.spellcheck = false;
        txt.onchange = (e) => this.funcEditorChange(e.target.value);
        dom.appendChild(txt);
      }
    }
    txt.style.display = "none";
    txt.style.minHeight = "100px";
    txt.style.height = "calc(100vh - 317px)";
    dom = document.getElementsByClassName("editable-range")[0];
    if (dom) dom.style.display = "block";

    // 最大化编辑区
    dom = document.getElementsByClassName('icon-fullscreen')[0];
    if (dom) {
      dom.title = '最大化';
      dom.onclick = this.funcToggleMax;
    }
  };

  // 编辑区内容与代码切换
  funcToggleSource = () => {
    const display = {
      block: "none",
      none: "block",
    };

    let dom = document.getElementsByClassName("editable-range")[0];
    if (dom) {
      dom.style.display = dom.style.display || "block";
      dom.style.display = display[dom.style.display];
    }

    dom = document.getElementById("txt_source");
    if (dom) {
      dom.style.display = display[dom.style.display];
      if (dom.style.display === "block") {
        const { state } = this;
        dom.value = htmlFormat(state.editorText);
      }
    }
  };

  // 编辑区最大化与恢复的切换
  funcToggleMax = () => {
    const dom = document.getElementsByClassName("editable-range")[0];
    if (!dom) return;

    const isWindow = dom.style.height === dom.getAttribute('dataHeight');
    const height = isWindow ? 'calc(100vh - 190px)' : dom.getAttribute('dataHeight');

    dom.style.height = height;

    const txt = document.getElementById("txt_source");
    if (txt) txt.style.height = height;

    const drawerContent = document.getElementById('drawerContent');
    if (drawerContent) {
      drawerContent.style.overflow = isWindow ? 'auto' : 'unset';
      if (isWindow) drawerContent.scrollTop = 231;
    }
  };

  // 编辑器正文更新
  funcEditorChange = (editorText) => {
    const dom = document.getElementById("txt_source");
    if (dom) dom.value = editorText;
    this.setState({ editorText });
  };

  render() {
    const { state, props } = this;
    const { getFieldDecorator } = props.form;
    const { errMsg, dataFail, taskTotal } = props[reqApi];
    const rate = Math.round(dataFail.length / taskTotal * 100);

    return (
      <PageHeaderLayout title={props.route.name}>
        <PageCard children={this.contentTable()} />

        <Modal
          width={modalWidth}
          title={(
            <div>
              <Icon type='warning' style={{ fontSize: 16 }} />
              <span> {errMsg}</span>
            </div>
          )}
          visible={state.visibleSend}
          onOk={() => this.setState({ visibleSend: false })}
          onCancel={() => this.setState({ visibleSend: false })}
          bodyStyle={{ padding: '0 24px' }}
          footer={(
            <IconButton
              text='关闭'
              onClick={() => this.setState({ visibleSend: false })}
            />
          )}
        >
          <List
            dataSource={dataFail}
            header='发送失败列表'
            footer={'发送失败占比：' + rate + '％'}
            renderItem={(item, i) => (
              <List.Item key={i}>
                <List.Item.Meta
                  title={item.name}
                  description={item.phone}
                />
              </List.Item>
            )}
          />
        </Modal>

        <Drawer
          width={window.isMobile ? window.innerWidth : modalWidth}
          title={state.dialogTitle}
          visible={state.visible}
          onClose={() => this.setState({ visible: false })}
          bodyStyle={{ padding: '24px 0 0 0' }}
          footerStyle={{ textAlign: 'right' }}
          footer={[
            <IconButton
              key='cancel'
              text='取消'
              type='default'
              onClick={() => this.setState({ visible: false })}
            />,
            <IconButton
              key='save'
              text='保存'
              loading={state.dialogLoading}
              style={{ marginLeft: 8 }}
              onClick={this.funcSave}
            />,
          ]}
        >
          <div
            id='drawerContent'
            style={{
              padding: '0 24px',
              height: 'calc(100vh - 132px)',
              overflow: 'hidden',
            }}
          >
            <Form>
              <Row gutter={{ md: 24, sm: 8 }}>
                <Col md={24} sm={24}>
                  <Form.Item label='公告标题' {...formItemLayout}>
                    {getFieldDecorator('title', {
                      rules: [{ required: true, message: '请输入公告标题' }],
                    })(<Input maxLength={20} autoFocus />)}
                  </Form.Item>
                </Col>

                <Col md={8} sm={24}>
                  <Form.Item label="开始时间" {...formItemLayout3}>
                    {getFieldDecorator('beginTime', {
                      initialValue: moment(), // 即刻生效
                    })(
                      <DatePicker
                        format="YYYY-MM-DD HH:mm"
                        showTime={{ format: 'HH:mm' }}
                        style={{ width: '100%' }}
                        disabledDate={now => now < moment().startOf('day')}
                      />
                    )}
                  </Form.Item>
                </Col>

                <Col md={8} sm={24}>
                  <Form.Item label="结束时间" {...formItemLayout3}>
                    {getFieldDecorator('endTime', {
                      initialValue: moment(
                        new Date().getFullYear() + '-08-31 23:59',
                        'YYYY-MM-DD HH:mm'
                      ),
                    })(
                      <DatePicker
                        format="YYYY-MM-DD HH:mm"
                        showTime={{ format: 'HH:mm' }}
                        style={{ width: '100%' }}
                        disabledDate={now => now < moment().startOf('day')}
                      />
                    )}
                  </Form.Item>
                </Col>

                <Col md={8} sm={24}>
                  <Form.Item label="显示顺序" {...formItemLayout3}>
                    {getFieldDecorator("sequ", {
                      initialValue: 0,
                    })(<InputNumber min={0} max={1000} style={{ width: '100%' }} />)}
                  </Form.Item>
                </Col>

                <Col span={24}>
                  <Form.Item>
                    <Editor
                      icons={editorIcons}
                      value={state.editorText}
                      onChange={this.funcEditorChange}
                    />
                  </Form.Item>
                </Col>
              </Row>
            </Form>
          </div>
        </Drawer>
      </PageHeaderLayout>
    );
  }
}

const page2 = Form.create()(page);
export default connect(({ notice, menu }) => ({ notice, menu }))(page2);
